Aprenda Python em 10 minutos
Python é uma linguagem de programação de alto nível e interpretada, conhecida por sua sintaxe concisa e recursos poderosos. Este tutorial é baseado na versão mais recente do Python 3.13+, ajudando você a aprender Python rapidamente.
1. Escrevendo Seu Primeiro Programa Python
Vamos começar com um programa simples. Crie um arquivo chamado hello.py
e insira o seguinte código:
print("Olá, Mundo!")
Salve o arquivo e execute o seguinte comando no terminal ou linha de comando:
python hello.py
A saída será:
Olá, Mundo!
Este programa simples demonstra a funcionalidade básica de saída do Python. A função print()
é usada para exibir informações de texto no console.
2. Sintaxe Básica
A sintaxe do Python é simples e fácil de entender. Python usa indentação para definir blocos de código, diferente de outras linguagens que usam chaves {}
.
# Este é um comentário
print("Olá, Mundo!")
Regras básicas de sintaxe no Python:
- Indentação: Por padrão, 4 espaços são usados para indicar o nível de um bloco de código. Por exemplo, o código dentro de funções ou loops deve ser indentado.
- Comentários: Comentários de uma linha começam com
#
, enquanto comentários de várias linhas usam aspas triplas"""
ou'''
. - Instruções: Normalmente, uma instrução por linha, sem necessidade de ponto e vírgula
;
no final. - Blocos de Código: Definidos por indentação, como em
if
,for
ou corpos de funções.
Exemplo com comentários de várias linhas:
"""
Este é um comentário de várias linhas,
que se estende por várias linhas.
"""
A indentação é uma característica essencial da sintaxe do Python, usada para definir a estrutura hierárquica dos blocos de código:
if True:
print("Esta linha está indentada")
print("Esta linha também está indentada")
print("Esta linha não está indentada")
3. Variáveis e Tipos de Dados
No Python, variáveis são contêineres para armazenar dados. Python é uma linguagem de tipagem dinâmica, o que significa que você não precisa declarar o tipo de uma variável com antecedência.
Regras básicas para nomeação de variáveis:
- Nomes de variáveis podem conter apenas letras, números e sublinhados.
- Nomes de variáveis não podem começar com um número.
- Nomes de variáveis são sensíveis a maiúsculas e minúsculas.
- Palavras-chave do Python não podem ser usadas como nomes de variáveis.
Os tipos de variáveis são determinados pelo valor atribuído. Os principais tipos de dados básicos do Python são:
- Inteiro (int): por exemplo,
42
ou-10
, sem limite de tamanho. - Ponto flutuante (float): por exemplo,
3.14
ou2.5e3
(notação científica). - String (str): por exemplo,
"olá"
ou'mundo'
, usando aspas simples ou duplas. - Booleano (bool):
True
ouFalse
. - NoneType (None): Representado por
None
, indicando nulo ou sem valor.
O Python suporta dicas de tipo para melhorar a legibilidade do código, usadas para verificação estática e suporte a IDEs, sem afetar o comportamento em tempo de execução:
nome: str = "Alice"
idade: int = 25
3.1 Tipos Numéricos (Number)
O Python suporta três tipos numéricos: inteiro (int), ponto flutuante (float) e complexo (complex).
# Inteiro
idade = 25
populacao = 1000000
# Ponto flutuante
temperatura = 36.5
pi = 3.14159
# Complexo
numero_complexo = 3 + 4j
3.2 String (String)
Strings são sequências de caracteres, delimitadas por aspas simples ou duplas.
aspas_simples = 'String com aspas simples'
aspas_duplas = "String com aspas duplas"
multilinha = """Esta é uma
string de várias linhas"""
Operações com strings:
texto = "Programação em Python"
print(len(texto)) # Comprimento da string
print(texto.upper()) # Converter para maiúsculas
print(texto.lower()) # Converter para minúsculas
print(texto[0]) # Acessar o primeiro caractere
print(texto[2:6]) # Fatiamento de string
3.3 Tipo Booleano (Boolean)
O tipo booleano tem dois valores: True
e False
.
esta_ativo = True
esta_completo = False
# Operações booleanas
resultado1 = True and False # False
resultado2 = True or False # True
resultado3 = not True # False
3.4 Tipo None (None)
None
representa um estado nulo ou sem valor.
valor = None
if valor is None:
print("O valor é nulo")
4. Estruturas de Dados
O Python oferece várias estruturas de dados integradas para armazenar e manipular dados. Abaixo estão as estruturas de dados mais usadas e suas aplicações.
4.1 Lista (List)
Uma lista é uma coleção ordenada e mutável. Você pode adicionar, remover ou modificar elementos em uma lista. Listas são definidas usando colchetes []
.
numeros = [1, 2, 3, 4, 5]
numeros.append(6) # Adicionar elemento
numeros.insert(0, 0) # Inserir em uma posição específica
numeros.remove(3) # Remover valor específico
numeros[0] = 10 # Modificar elemento
print(numeros) # [10, 2, 4, 5, 6]
Fatiamento de lista para acessar sublistas:
numeros = [10, 20, 30, 40, 50]
print(numeros[1:4]) # Saída: [20, 30, 40]
print(numeros[:3]) # Saída: [10, 20, 30]
print(numeros[-2:]) # Saída: [40, 50]
Compreensão de lista:
quadrados = [x**2 for x in range(5)]
print(quadrados) # [0, 1, 4, 9, 16]
quadrados_pares = [x**2 for x in range(10) if x % 2 == 0]
print(quadrados_pares) # [0, 4, 16, 36, 64]
4.2 Tupla (Tuple)
Uma tupla é uma coleção ordenada, mas imutável. Após criada, seus elementos não podem ser modificados. Tuplas são definidas usando parênteses ()
. Devido à sua imutabilidade, as tuplas são geralmente mais rápidas que as listas e podem ser usadas como chaves de dicionários.
ponto = (10, 20)
x, y = ponto # Desempacotamento
print(x, y) # Saída: 10 20
Tuplas de elemento único requerem uma vírgula:
tupla_unica = (42,)
4.3 Dicionário (Dict)
Um dicionário é uma coleção não ordenada (ordenada no Python 3.7+) de pares chave-valor. Cada chave é única e associada a um valor. Dicionários são definidos usando chaves {}
.
estudante = {
"nome": "John",
"idade": 20,
"curso": "Ciência da Computação"
}
# Acessando e modificando dicionário
print(estudante["nome"])
estudante["idade"] = 21
estudante["gpa"] = 3.8
# Acesso seguro
print(estudante.get("telefone", "Não fornecido"))
# Iterando sobre dicionário
for chave, valor in estudante.items():
print(f"{chave}: {valor}")
Compreensão de dicionário:
# Criar um dicionário de quadrados
dicionario_quadrados = {x: x**2 for x in range(5)}
print(dicionario_quadrados) # {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}
# Compreensão de dicionário condicional
dicionario_quadrados_pares = {x: x**2 for x in range(10) if x % 2 == 0}
print(dicionario_quadrados_pares) # {0: 0, 2: 4, 4: 16, 6: 36, 8: 64}
4.4 Conjunto (Set)
Um conjunto é uma coleção não ordenada sem elementos duplicados. Definido usando chaves {}
ou set()
.
# Criando um conjunto
frutas = {"maçã", "banana", "laranja"}
numeros = set([1, 2, 3, 3, 4, 4, 5]) # Deduplicação automática
print(numeros) # {1, 2, 3, 4, 5}
# Operações com conjuntos
conjunto1 = {1, 2, 3, 4}
conjunto2 = {3, 4, 5, 6}
print(conjunto1 | conjunto2) # União: {1, 2, 3, 4, 5, 6}
print(conjunto1 & conjunto2) # Interseção: {3, 4}
print(conjunto1 - conjunto2) # Diferença: {1, 2}
print(conjunto1 ^ conjunto2) # Diferença simétrica: {1, 2, 5, 6}
5. Operações e Operadores
O Python fornece um conjunto rico de operadores para várias computações e comparações, incluindo operadores aritméticos, de comparação, lógicos, bit a bit e de identidade.
- Operadores Aritméticos:
+
,-
,*
,/
,//
(divisão inteira),%
(módulo),**
(exponenciação). - Operadores de Comparação:
==
,!=
,>
,<
,>=
,<=
. - Operadores Lógicos:
and
,or
,not
. - Operadores de Pertencimento:
in
,not in
. - Operadores de Identidade:
is
,is not
.
5.1 Operadores Aritméticos
Os operadores aritméticos são usados para operações matemáticas. A precedência dos operadores segue as regras matemáticas (por exemplo, **
tem maior precedência que +
ou -
). Parênteses ()
podem ser usados para alterar a precedência.
a, b = 10, 3
print(f"Adição: {a + b}") # 13
print(f"Subtração: {a - b}") # 7
print(f"Multiplicação: {a * b}") # 30
print(f"Divisão: {a / b}") # 3.333...
print(f"Divisão Inteira: {a // b}") # 3
print(f"Módulo: {a % b}") # 1
print(f"Exponenciação: {a ** b}") # 1000
5.2 Operadores de Comparação
Os operadores de comparação comparam dois valores e retornam um booleano (True
ou False
).
x, y = 5, 10
print(f"Igual: {x == y}") # False
print(f"Diferente: {x != y}") # True
print(f"Maior que: {x > y}") # False
print(f"Menor que: {x < y}") # True
print(f"Maior ou igual: {x >= y}") # False
print(f"Menor ou igual: {x <= y}") # True
5.3 Operadores Lógicos
Os operadores lógicos combinam ou manipulam valores booleanos (True
ou False
), geralmente usados em instruções condicionais.
a, b = True, False
print(f"Operação AND: {a and b}") # False
print(f"Operação OR: {a or b}") # True
print(f"Operação NOT: {not a}") # False
5.4 Operadores de Identidade
O operador is
compara a identidade de dois objetos, verificando se eles referem-se ao mesmo endereço de memória (não apenas valores iguais). Ele difere de ==
, que compara o conteúdo.
lista1 = [1, 2, 3]
lista2 = [1, 2, 3]
lista3 = lista1
print(f"lista1 is lista2: {lista1 is lista2}") # False
print(f"lista1 is lista3: {lista1 is lista3}") # True
print(f"lista1 == lista2: {lista1 == lista2}") # True
5.5 Operadores de Pertencimento
Os operadores de pertencimento testam se um valor é membro de uma sequência (por exemplo, lista, tupla, string, conjunto), retornando um booleano.
frutas = ["maçã", "banana", "laranja"]
print(f"'maçã' in frutas: {'maçã' in frutas}") # True
print(f"'uva' not in frutas: {'uva' not in frutas}") # True
6. Fluxo de Controle
O Python oferece várias instruções de fluxo de controle para gerenciar a ordem de execução de um programa.
6.1 Instruções if
A instrução if
avalia uma condição e executa seu bloco se a condição for True
. Use elif
e else
para condições complexas.
idade = 20
if idade >= 18:
print("Adulto")
elif idade >= 13:
print("Adolescente")
else:
print("Criança")
6.2 Loops for
O loop for
itera sobre um objeto iterável (por exemplo, lista, tupla, string ou range).
# Iterando sobre uma lista
frutas = ["maçã", "banana", "cereja"]
for fruta in frutas:
print(fruta)
# Usando range() para looping
for i in range(5):
print(i) # Saída: 0, 1, 2, 3, 4
6.3 Loops while
O loop while
continua executando um bloco enquanto sua condição permanecer True
.
contador = 0
while contador < 5:
print(contador)
contador += 1
- break e continue:
break
sai do loop,continue
pula a iteração atual.
for i in range(10):
if i == 5:
break
if i % 2 == 0:
continue
print(i) # Saída: 1, 3
6.4 Instruções match
Introduzidas no Python 3.10, as instruções match
oferecem correspondência de padrões estruturais poderosa, funcionando como uma alternativa avançada às cadeias if/elif/else
.
status_http = 200
match status_http:
case 200 | 201:
print("Sucesso")
case 404:
print("Não encontrado")
case 500:
print("Erro no servidor")
case _: # Coringa, corresponde a qualquer outro caso
print("Status desconhecido")
7. Entrada e Saída
7.1 Entrada e Saída Básicas
Use a função input()
para obter entrada do usuário e a função print()
para exibir informações.
# Obtendo entrada do usuário
nome = input("Por favor, insira seu nome: ")
idade = int(input("Por favor, insira sua idade: "))
# Exibindo informações
print("Bem-vindo", nome)
print("Você tem", idade, "anos")
7.2 Saída Formatada (f-strings)
Introduzidas no Python 3.6+, as f-strings (literais de string formatados) são uma maneira conveniente e poderosa de formatar strings. Prefixe uma string com f
ou F
e incorpore variáveis ou expressões entre chaves {}
.
usuario = "Alice"
itens = 3
custo_total = 45.5
# Usando f-string para mensagem formatada
mensagem = f"O usuário {usuario} comprou {itens} itens por ${custo_total:.2f}."
print(mensagem)
# Expressões em f-strings
print(f"2 + 3 é igual a {2 + 3}")
Expressões e chamadas de funções em f-strings:
largura = 10
altura = 5
# Usando expressões em f-strings
area = f"Área do retângulo: {largura * altura}"
print(area)
# Chamando funções
texto = "python"
formatado = f"Maiúsculas: {texto.upper()}, Comprimento: {len(texto)}"
print(formatado)
Opções de formatação em f-strings:
pi = 3.14159265359
numero_grande = 1234567
# Formatação de números
print(f"Pi (2 decimais): {pi:.2f}")
print(f"Pi (4 decimais): {pi:.4f}")
print(f"Número grande (milhares): {numero_grande:,}")
print(f"Percentual: {0.85:.1%}")
# Alinhamento de strings
nome = "Python"
print(f"Alinhamento à esquerda: '{nome:<10}'")
print(f"Alinhamento à direita: '{nome:>10}'")
print(f"Alinhamento ao centro: '{nome:^10}'")
Formatação de data e hora com f-strings:
from datetime import datetime
agora = datetime.now()
print(f"Hora atual: {agora}")
print(f"Hora formatada: {agora:%Y-%m-%d %H:%M:%S}")
print(f"Apenas data: {agora:%Y-%m-%d}")
9. Funções
Funções no Python são blocos de código reutilizáveis para tarefas específicas, definidas usando a palavra-chave def
, suportando parâmetros padrão, argumentos variáveis e argumentos nomeados.
Definição Básica de Função:
def saudar(nome):
"""Função de saudação"""
return f"Olá, {nome}!"
# Chamando a função
mensagem = saudar("John")
print(mensagem)
Argumentos Nomeados:
Argumentos nomeados são passados usando a sintaxe nome_do_parametro=valor
.
def saudar(nome, saudacao="Olá"):
return f"{saudacao}, {nome}!"
print(saudar("Alice")) # Saída: Olá, Alice!
print(saudar("Bob", "Oi")) # Saída: Oi, Bob!
Argumentos Variáveis:
Argumentos variáveis permitem que funções aceitem um número arbitrário de argumentos, seja posicionais (*args
) ou nomeados (**kwargs
).
# Argumentos posicionais variáveis (*args)
def somar_numeros(*args):
return sum(args)
print(somar_numeros(1, 2, 3, 4)) # Saída: 10
# Argumentos nomeados variáveis (**kwargs)
def exibir_kwargs(**kwargs):
for chave, valor in kwargs.items():
print(f"{chave}: {valor}")
exibir_kwargs(nome="Alice", idade=25, cidade="Pequim")
Anotações de Função:
Anotações de função adicionam metadados descritivos aos parâmetros e valores de retorno, melhorando a legibilidade e documentação.
def calcular_area(comprimento: float, largura: float) -> float:
"""Calcula a área de um retângulo"""
return comprimento * largura
def processar_usuario(nome: str, idade: int, ativo: bool = True) -> dict:
"""Processa informações do usuário"""
return {
"nome": nome,
"idade": idade,
"ativo": ativo
}
10. Expressões Lambda
Expressões lambda criam funções anônimas, fornecendo uma maneira concisa de definir pequenas funções.
quadrado = lambda x: x ** 2
print(quadrado(5)) # Saída: 25
Comumente usadas com funções de ordem superior como map
ou filter
:
numeros = [1, 2, 3, 4]
quadrados = list(map(lambda x: x ** 2, numeros))
print(quadrados) # Saída: [1, 4, 9, 16]
11. Classes e Objetos
O Python suporta programação orientada a objetos usando a palavra-chave class
:
class Pessoa:
"""Classe Pessoa"""
def __init__(self, nome, idade):
"""Construtor"""
self.nome = nome
self.idade = idade
def apresentar(self):
"""Método de apresentação"""
return f"Eu sou {self.nome}, {self.idade} anos"
def fazer_aniversario(self):
"""Método de aniversário"""
self.idade += 1
return f"{self.nome} fez aniversário, agora tem {self.idade} anos"
# Criando objetos
pessoa1 = Pessoa("John", 25)
pessoa2 = Pessoa("Jane", 30)
print(pessoa1.apresentar())
print(pessoa2.fazer_aniversario())
11.1 Atributos de Classe e Instância
No Python, atributos de classe e atributos de instância são dois tipos de atributos para armazenar dados em classes e objetos.
- Atributos de Classe: Definidos fora dos métodos, pertencem à própria classe e são compartilhados entre todas as instâncias.
- Atributos de Instância: Definidos em métodos (geralmente
__init__
), ligados a instâncias específicas viaself
.
class Estudante:
# Atributos de classe
escola = "Universidade de Stanford"
contador_estudantes = 0
def __init__(self, nome, curso):
# Atributos de instância
self.nome = nome
self.curso = curso
Estudante.contador_estudantes += 1
@classmethod
def obter_contador_estudantes(cls):
"""Método de classe"""
return cls.contador_estudantes
@staticmethod
def idade_valida(idade):
"""Método estático"""
return 0 < idade < 150
# Exemplo de uso
estudante1 = Estudante("John", "Ciência da Computação")
estudante2 = Estudante("Jane", "Matemática")
print(f"Escola: {Estudante.escola}")
print(f"Total de estudantes: {Estudante.obter_contador_estudantes()}")
print(f"Idade válida: {Estudante.idade_valida(20)}")
11.2 Herança de Classe
A herança permite que uma classe (subclasse) herde atributos e métodos de outra classe (classe pai), possibilitando reutilização e extensão de código.
class Animal:
def __init__(self, nome, especie):
self.nome = nome
self.especie = especie
def fazer_som(self):
return f"{self.nome} faz um som"
def info(self):
return f"{self.nome} é um {self.especie}"
class Cachorro(Animal):
def __init__(self, nome, raca):
super().__init__(nome, "Cachorro")
self.raca = raca
def fazer_som(self):
return f"{self.nome} late"
def buscar(self):
return f"{self.nome} busca a bola"
class Gato(Animal):
def __init__(self, nome, cor):
super().__init__(nome, "Gato")
self.cor = cor
def fazer_som(self):
return f"{self.nome} mia"
def escalar(self):
return f"{self.nome} escala uma árvore"
# Usando herança
cachorro = Cachorro("Buddy", "Golden Retriever")
gato = Gato("Mimi", "Laranja")
print(cachorro.info())
print(cachorro.fazer_som())
print(cachorro.buscar())
print(gato.info())
print(gato.fazer_som())
print(gato.escalar())
11.3 Métodos Especiais (Métodos Mágicos)
Métodos especiais (ou métodos mágicos) são métodos com sublinhado duplo que definem comportamentos específicos, chamados automaticamente pelo Python em certos cenários.
class Retangulo:
def __init__(self, largura, altura):
self.largura = largura
self.altura = altura
def __str__(self):
"""Representação em string"""
return f"Retângulo({self.largura}x{self.altura})"
def __repr__(self):
"""Representação oficial em string"""
return f"Retangulo(largura={self.largura}, altura={self.altura})"
def __eq__(self, outro):
"""Comparação de igualdade"""
if isinstance(outro, Retangulo):
return self.largura == outro.largura and self.altura == outro.altura
return False
def __lt__(self, outro):
"""Comparação de menor que (por área)"""
if isinstance(outro, Retangulo):
return self.area() < outro.area()
return NotImplemented
def __add__(self, outro):
"""Operação de adição"""
if isinstance(outro, Retangulo):
return Retangulo(self.largura + outro.largura, self.altura + outro.altura)
return NotImplemented
def area(self):
"""Calcula a área"""
return self.largura * self.altura
# Usando métodos especiais
ret1 = Retangulo(3, 4)
ret2 = Retangulo(5, 6)
ret3 = Retangulo(3, 4)
print(ret1) # Retângulo(3x4)
print(repr(ret1)) # Retangulo(largura=3, altura=4)
print(ret1 == ret3) # True
print(ret1 < ret2) # True
print(ret1 + ret2) # Retângulo(8x10)
12. Gerenciadores de Contexto
Gerenciadores de contexto garantem a aquisição e liberação adequada de recursos, comumente usados com a instrução with
para gerenciar recursos, como arquivos ou conexões de banco de dados.
12.1 Usando Gerenciadores de Contexto
Operações com arquivos são um caso de uso comum para gerenciadores de contexto:
with open("exemplo.txt", "r") as arquivo:
conteudo = arquivo.read()
print(conteudo)
A instrução with
garante que o arquivo seja fechado automaticamente após as operações.
12.2 Gerenciadores de Contexto Personalizados
Crie gerenciadores de contexto personalizados definindo os métodos __enter__
e __exit__
:
class ConexaoBancoDados:
def __init__(self, nome_banco):
self.nome_banco = nome_banco
self.conexao = None
def __enter__(self):
"""Chamado ao entrar no contexto"""
print(f"Conectando ao banco de dados: {self.nome_banco}")
self.conexao = f"Conexão com {self.nome_banco}"
return self.conexao
def __exit__(self, tipo_excecao, valor_excecao, traceback):
"""Chamado ao sair do contexto"""
print(f"Fechando conexão com banco de dados: {self.nome_banco}")
if tipo_excecao:
print(f"Ocorreu uma exceção: {tipo_excecao.__name__}: {valor_excecao}")
self.conexao = None
return False # Não suprimir exceções
# Usando gerenciador de contexto personalizado
with ConexaoBancoDados("banco_de_usuarios") as conn:
print(f"Usando conexão: {conn}")
print("Realizando operações no banco de dados...")
Usando o módulo contextlib
para criar gerenciadores de contexto:
from contextlib import contextmanager
import time
@contextmanager
def temporizador(nome_operacao):
"""Gerenciador de contexto para temporização"""
print(f"Iniciando {nome_operacao}")
inicio = time.time()
try:
yield
finally:
fim = time.time()
print(f"{nome_operacao} concluído em {fim - inicio:.2f} segundos")
# Usando gerenciador de contexto baseado em decorador
with temporizador("processamento de dados"):
# Simular operação demorada
time.sleep(1)
print("Processando dados...")
13. Tratamento de Exceções
O tratamento de exceções garante a robustez do programa, usando try
, except
, else
e finally
para gerenciar exceções.
try:
resultado = 10 / 0
except ZeroDivisionError:
print("Não é possível dividir por zero!")
else:
print("Divisão bem-sucedida")
finally:
print("Isso sempre é executado")
Saída:
Não é possível dividir por zero!
Isso sempre é executado
14. Operações com Arquivos
O Python fornece métodos simples para leitura e escrita de arquivos, normalmente usados com gerenciadores de contexto.
14.1 Lendo Arquivos
Lendo o conteúdo de um arquivo de texto:
with open("exemplo.txt", "r") as arquivo:
conteudo = arquivo.read()
print(conteudo)
Lendo linha por linha:
with open("exemplo.txt", "r") as arquivo:
for linha in arquivo:
print(linha.strip())
14.2 Escrevendo Arquivos
Escrevendo em um arquivo de texto:
with open("saida.txt", "w") as arquivo:
arquivo.write("Olá, Python!\n")
Adicionando conteúdo:
with open("saida.txt", "a") as arquivo:
arquivo.write("Adicionando novo conteúdo.\n")
15. Módulos e Pacotes
Módulos são arquivos contendo código Python, e pacotes são diretórios contendo vários módulos. Importe módulos usando import
:
import math
print(math.sqrt(16)) # Saída: 4.0
Exemplo de módulo personalizado (suponha que o arquivo seja chamado meu_modulo.py
):
# meu_modulo.py
def dizer_ola():
return "Olá do módulo!"
Importando e usando:
import meu_modulo
print(meu_modulo.dizer_ola()) # Saída: Olá do módulo!
16. Escopo e Namespace
16.1 Escopo
O escopo define a região onde uma variável é acessível. O Python segue a regra LEGB para busca de variáveis:
- L (Local): Dentro de uma função ou método de classe.
- E (Enclosing): Na função externa de uma função aninhada (closure).
- G (Global): No nível do módulo.
- B (Built-in): Funções e exceções embutidas como
print()
oulen()
.
x = "x global"
def funcao_externa():
x = "x envolvente"
def funcao_interna():
x = "x local"
print(x) # Acessa o escopo local x
funcao_interna()
print(x) # Acessa o escopo envolvente x
funcao_externa()
print(x) # Acessa o escopo global x
Usando global
ou nonlocal
para modificar variáveis de escopo:
x = "global"
def modificar_global():
global x
x = "modificado"
modificar_global()
print(x) # Saída: modificado
16.2 Namespace
Um namespace é um mapeamento de nomes para objetos, como um dicionário onde as chaves são nomes de variáveis e os valores são os objetos.
Cada módulo, função e classe tem seu próprio namespace, evitando conflitos de nomes. Use globals()
e locals()
para inspecionar namespaces.
uma_variavel = 10
def alguma_funcao():
outra_variavel = 20
# locals() retorna o dicionário do namespace local atual
print(f"Locais: {locals()}")
print(f"Globais: {globals().keys()}") # Imprime as chaves do namespace global
alguma_funcao()
17. Geradores
Geradores são iteradores especiais que geram valores sob demanda, em vez de criar todos os valores de uma vez, tornando-os eficientes em memória para grandes conjuntos de dados.
Geradores usam a palavra-chave yield
para retornar valores de forma preguiçosa:
def fibonacci(n):
a, b = 0, 1
for _ in range(n):
yield a
a, b = b, a + b
for num in fibonacci(5):
print(num) # Saída: 0, 1, 1, 2, 3
18. Multithreading
Multithreading permite que um programa execute várias operações simultaneamente, útil para tarefas limitadas por I/O, como requisições de rede ou operações com arquivos.
O módulo threading
do Python fornece ferramentas para criar e gerenciar threads. Devido ao Global Interpreter Lock (GIL), o multithreading não alcança verdadeiro paralelismo de CPU em um único processo, mas melhora significativamente o desempenho para tarefas limitadas por I/O.
import threading
import time
def trabalhador(nome_thread):
print(f"Thread {nome_thread} iniciando...")
time.sleep(2) # Simula operação demorada
print(f"Thread {nome_thread} finalizada.")
# Criar threads
thread1 = threading.Thread(target=trabalhador, args=("A",))
thread2 = threading.Thread(target=trabalhador, args=("B",))
# Iniciar threads
thread1.start()
thread2.start()
# Aguardar a conclusão de todas as threads
thread1.join()
thread2.join()
print("Todas as threads concluídas.")
19. Programação Assíncrona
A programação assíncrona é ideal para cenários de alta I/O e alta concorrência, usando um loop de eventos para gerenciar tarefas em vez de threads.
O Python suporta programação assíncrona por meio da biblioteca asyncio
e da sintaxe async/await
.
async def
: Define uma co-rotina.await
: Pausa a execução da co-rotina, aguardando a conclusão de um objeto aguardável.
import asyncio
async def dizer_ola():
print("Olá")
await asyncio.sleep(1) # Sono não bloqueante, simulando I/O
print("Mundo")
async def principal():
# Criar e aguardar uma tarefa
await asyncio.create_task(dizer_ola())
# Executar a co-rotina principal
asyncio.run(principal())
Saída:
Olá
Mundo